#include <odb/database.hxx>
#include <odb/mysql/transaction.hxx>
#include <odb/mysql/database.hxx>

#include "student.h"
#include "student-odb.hxx"

// 数据库连接配置常量
const std::string HOST = "192.168.65.130";  // 数据库主机IP
const std::string USER = "root";           // 数据库用户名
const std::string PASS = "123456";         // 数据库密码
const std::string DBNAME = "mytest";       // 数据库名
const unsigned int PORT = 3306;           // MySQL默认端口
const std::string CSET = "utf8";           // 字符集（支持中文）

// 查询“一年级一班”的学生列表
void get_classes_students(std::unique_ptr<odb::mysql::database> &handler, int class_id) {
	try {
		// 开启事务（ODB 操作必须在事务中执行）
		odb::transaction tx(handler->begin());
		auto &db = tx.database();// 获取事务对应的数据库对象

		// 定义查询条件类型和结果集类型
		typedef odb::query<ClassesStudent> Query;
		typedef odb::result<ClassesStudent> Result;

		// 执行查询：班级名称为“一年级一班”的关联数据
		Result res(db.query<ClassesStudent>(Query::Classes::name == "一年级一班"));

		// 遍历结果集，输出班级和学生信息
        for (auto it = res.begin(); it != res.end(); ++it) {
            if (it->classes) {
                std::cout << "班级:" << it->classes->name() << "\t";
            }
            if (it->student) {
                std::cout << "姓名:" << it->student->name() << std::endl;
            }
        }
		tx.commit();// 提交事务，使操作生效
	} catch(odb::exception &e) {
		std::cout << "odb error: " << e.what() << std::endl;
	}
}

// 查询名为“赵六”的学生详情
void get_detail_student(std::unique_ptr<odb::mysql::database> &handler, int sn) {
	try {
		odb::transaction tx(handler->begin());
		auto &db = tx.database();

		typedef odb::query<DetailStudent> Query;
        typedef odb::result<DetailStudent> Result;

		// 执行查询：学生姓名为“赵六”的关联数据
		Result res(db.query<DetailStudent>(Query::Student::name == "赵六"));
		// 遍历结果集，输出班级和学生信息
        for (auto it = res.begin(); it != res.end(); ++it) {
            if (it->classes) {
                std::cout << "班级:" << it->classes->name() << "\t";
            }
            if (it->student) {
                std::cout << "姓名:" << it->student->name() << std::endl;
            }
        }
        tx.commit();  // 提交事务
 	} catch(odb::exception &e) {
		std::cout << "odb error: " << e.what() << std::endl;
	}
}

int main()
{
	// 1. 构造数据库连接池（大小为5）
	std::unique_ptr<odb::mysql::connection_factory> pool
		(new odb::mysql::connection_pool_factory(5));

	// 2. 构造数据库操作句柄（传入连接信息和连接池）
	auto handler = std::make_unique<odb::mysql::database>(
		USER, PASS, DBNAME, HOST, PORT, nullptr, CSET, 0, std::move(pool)
	);

	// 3. 执行数据操作
    get_classes_students(handler, 1);
    get_detail_student(handler, 2);

	return 0;
}